import logging

import cv2
import pyzbar.pyzbar as pyzbar

import settings as st
from control.task import Task, TASK_LOOP
import runtime


logger = logging.getLogger(__name__)


def _preprocess(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    if __debug__:
        cv2.imshow('gray_qr', gray)
    
    return gray


class TaskScanQR(Task):
    def __init__(self, cap):
        """
        :param cap: cv2.VideoCapture()
        """
        Task.__init__(self, task_type=TASK_LOOP)
        self.cap = cap
        self._use_preprocess = True  # 是否预处理
    
    # application interface
    def enable_preprocess(self):
        self._use_preprocess = True
    
    # application interface
    def disable_preprocess(self):
        self._use_preprocess = False
    
    def work(self):
        ret, raw = self.cap.read()
        if not ret:
            logger.info('read camera failed')
            return '', []  # send nothing
        
        if self._use_preprocess:
            im = _preprocess(raw)
        
        qr_data = pyzbar.decode(raw)    # 识别二维码
        if __debug__ and not self._use_preprocess:
            cv2.imshow('raw', raw)
            cv2.waitKey(1)
        
        if len(qr_data) == 0:
            logger.debug('no QR code detected')
            return '', []  # send nothing
        else:
            # 将二维码结果转换为整数, 以便于发送
            codes = [x.data.decode('ascii') for x in qr_data]  # bytes to str
            codes = [(int(x[0]), int(x[1])) for x in codes]  # str to int
            
            # 比赛中实际只会出现一个二维码, 因此取出第一个元素
            runtime.num_stuff, runtime.num_dst = codes[0]
            
            logger.debug('scaned: {}'.format(codes[0]))
            return st.LB_RSLT_QR, codes[0]


if __name__ == '__main__':
    cap = cv2.VideoCapture(0)
    tk = TaskScanQR(cap)
    
    while True:
        print(tk.work())
        
        k = cv2.waitKey(50) & 0xFF
        if k == 27:  # Esc
            exit()
